package com.leantech.android.browser.ui.favorites.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import coil.load
import com.cscj.android.repository.db.entity.BrowseHistoryEntity
import com.leantech.android.browser.R
import com.leantech.android.browser.databinding.ItemFavoritesBinding
import com.leantech.android.browser.databinding.ItemHistoryTitleBinding
import com.leantech.android.browser.ui.favorites.vm.BrowserHistoryViewModel
import com.leantech.android.browser.utils.onThrottleClick
import com.leantech.android.browser.utils.show
import com.cscj.android.utils.BitmapUtils.asBitmap

class BrowserHistoryAdapter(private val callback: HistoryAdapterCallback) :
    ListAdapter<BrowserHistoryViewModel.HistoryItem, ViewHolder>(diffCallback) {

    companion object {
        private val diffCallback =
            object : DiffUtil.ItemCallback<BrowserHistoryViewModel.HistoryItem>() {
                override fun areItemsTheSame(
                    oldItem: BrowserHistoryViewModel.HistoryItem,
                    newItem: BrowserHistoryViewModel.HistoryItem
                ): Boolean {
                    return (oldItem is BrowserHistoryViewModel.HistoryItem.Title && newItem is BrowserHistoryViewModel.HistoryItem.Title && oldItem.title == newItem.title) || (oldItem is BrowserHistoryViewModel.HistoryItem.Item && newItem is BrowserHistoryViewModel.HistoryItem.Item && oldItem.item.id == newItem.item.id)
                }

                override fun areContentsTheSame(
                    oldItem: BrowserHistoryViewModel.HistoryItem,
                    newItem: BrowserHistoryViewModel.HistoryItem
                ): Boolean {
                    return (oldItem is BrowserHistoryViewModel.HistoryItem.Title && newItem is BrowserHistoryViewModel.HistoryItem.Title && oldItem.title == newItem.title) || (oldItem is BrowserHistoryViewModel.HistoryItem.Item && newItem is BrowserHistoryViewModel.HistoryItem.Item && oldItem.item == newItem.item)
                }
            }


        private const val PayloadEditModeChange = 1
        private const val PayloadCheckedChange = 2
        private const val ItemTypeTitle = 1
        private const val ItemTypeDefault = 2
    }

    private var editMode = false
    private val checkedIds = hashSetOf<Int>()


    fun updateEditMode(on: Boolean) {
        if (on == editMode) return
        editMode = on
        notifyItemRangeChanged(0, itemCount, PayloadEditModeChange)
    }

    fun selectItems(ids: Collection<Int>) {
        if (!editMode) return
        checkedIds.clear()
        checkedIds.addAll(ids)
        notifyItemRangeChanged(0, itemCount, PayloadCheckedChange)
    }

    fun selectItemsNotNotify(ids: Set<Int>) {
        if (!editMode) return
        checkedIds.clear()
        checkedIds.addAll(ids)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return when(viewType){
            ItemTypeTitle -> {
                val binding = ItemHistoryTitleBinding.inflate(inflater, parent, false)
                HistoryTitleViewHolder(binding)
            }
            else -> {
                val binding = ItemFavoritesBinding.inflate(inflater, parent, false)
                HistoryItemViewHolder(binding)
            }
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = getItem(position)

        if (holder is HistoryItemViewHolder && item is BrowserHistoryViewModel.HistoryItem.Item) {
            holder.bind(item.item, editMode, checkedIds.contains(item.item.id), callback)
        } else if (holder is HistoryTitleViewHolder && item is BrowserHistoryViewModel.HistoryItem.Title) {
            holder.bind(item.title)
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads)
        } else {
            val item = getItem(position)
            if (holder is HistoryItemViewHolder && item is BrowserHistoryViewModel.HistoryItem.Item) {
                payloads.forEach { payload ->
                    when (payload) {
                        PayloadEditModeChange -> {
                            holder.updateEditMode(item.item, editMode, callback)
                        }

                        PayloadCheckedChange -> {
                            holder.updateChecked(checkedIds.contains(item.item.id))
                        }

                        else -> {
                            super.onBindViewHolder(holder, position, payloads)
                        }
                    }
                }
            }

        }
    }

    override fun getItemViewType(position: Int): Int {
        val item = getItem(position)
        return if (item is BrowserHistoryViewModel.HistoryItem.Title) ItemTypeTitle else ItemTypeDefault
    }

    interface HistoryAdapterCallback {

        fun onHistoryItemClick(data: BrowseHistoryEntity, position: Int)

        fun onHistoryItemChecked(data: BrowseHistoryEntity, position: Int, checked: Boolean)

    }


    class HistoryTitleViewHolder(val binding: ItemHistoryTitleBinding) : ViewHolder(binding.root) {

        fun bind(title: String) {
            binding.text.text = title
        }

    }

    class HistoryItemViewHolder(val binding: ItemFavoritesBinding) : ViewHolder(binding.root) {

        fun bind(
            item: BrowseHistoryEntity,
            editMode: Boolean,
            checked: Boolean,
            adapterCallback: HistoryAdapterCallback
        ) {
            updateEditMode(item, editMode, adapterCallback)
            updateChecked(checked)
            val icon = item.icon?.asBitmap()
            if (icon == null) {
                binding.favicon.load(R.drawable.icon_default_link)
            } else {
                binding.favicon.load(icon)
            }
            binding.title.text = item.title
            binding.content.text = item.url
        }

        fun updateEditMode(
            item: BrowseHistoryEntity, editMode: Boolean, adapterCallback: HistoryAdapterCallback
        ) {
            binding.checkbox.show(editMode)
            if (editMode) {
                binding.checkbox.setOnCheckedChangeListener { _, isChecked ->
                    adapterCallback.onHistoryItemChecked(item, bindingAdapterPosition, isChecked)
                }
            } else {
                binding.checkbox.setOnCheckedChangeListener(null)
            }
            binding.root.onThrottleClick {
                if (editMode) {
                    binding.checkbox.toggle()
                } else {
                    adapterCallback.onHistoryItemClick(item, bindingAdapterPosition)
                }
            }
        }

        fun updateChecked(checked: Boolean) {
            binding.checkbox.isChecked = checked
        }

    }

}